home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 45 / Amiga Format CD45 (1999-09)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-11].iso / -coverdisks- / 129a / amimirror / developer / commodity / source / amimirror.c next >
C/C++ Source or Header  |  1999-08-17  |  30KB  |  907 lines

  1. #include "AmiMirror.h"
  2.  
  3. //--------------------------------------------------------------------
  4. // Make program's message with EasyRequest()
  5.  
  6. LONG MakeRequest (ULONG title, ULONG text, ULONG buttons, APTR arg1, ...)
  7. {
  8.   struct EasyStruct es = { sizeof(struct EasyStruct), 0L, NULL, NULL, NULL };
  9.  
  10.   es.es_Title        = GETMES(title);
  11.   es.es_TextFormat   = GETMES(text);
  12.   es.es_GadgetFormat = GETMES(buttons);
  13.  
  14.   DisplayBeep (NULL);
  15.   return (EasyRequestArgs (NULL, &es, NULL, &arg1));
  16. }
  17. //--------------------------------------------------------------------
  18. // Translate DOS-error code into descriptor string
  19.  
  20. STRPTR FaultStr (LONG error, STRPTR buffer)
  21. {
  22.   Fault (error, GETMES(DOS_ERROR_STR), buffer, 2*FAULT_MAX);
  23.   return (buffer);
  24. }
  25. //--------------------------------------------------------------------
  26. // Realise the memory allocated for the patterns' list
  27.  
  28. void FreePatList (void)
  29. {
  30.   struct Node *node;
  31.  
  32.   ObtainSemaphore (&Sema);
  33.   while (node = RemTail (&PatList))
  34.     FreeVec (node);
  35.   ReleaseSemaphore (&Sema);
  36. }
  37. //--------------------------------------------------------------------
  38. // Realise work buffers of patched function
  39.  
  40. void FreeWBuf (struct WorkBuf *wb, BOOL force)
  41. {
  42.   if (wb->wb_inbuf)
  43.     {
  44.       FreeVec (wb->wb_inbuf);
  45.       wb->wb_inbuf = NULL;
  46.     }
  47.   if (force)
  48.     FreeVec (wb);
  49. }
  50. //--------------------------------------------------------------------
  51. // Allocate work buffers for patch function
  52. // !!! We must never rely upon that any task have enough stack space for all needed buffers!!!
  53.  
  54. struct WorkBuf * AllocWBuf (void)
  55. {
  56.   struct WorkBuf *wb;
  57.  
  58.   if (wb = AllocVec (sizeof(struct WorkBuf), MEMF_PUBLIC))
  59.     {
  60.       wb->wb_inbuf = NULL;
  61.       wb->wb_inlen = 0L;
  62.     }
  63.   else
  64.     MakeRequest (REQ_TITLE_ERROR, OUT_MEM, CANCEL_BUT, NULL);
  65.   return (wb);
  66. }
  67. //--------------------------------------------------------------------
  68. // Trace patterns' list for suitable pattern
  69. struct PatternNode * TracePatList (ULONG function, struct WorkBuf *wb)
  70. {
  71.   STRPTR str;
  72.   struct Node *node;
  73.  
  74.   stcgfn (wb->wb_name, wb->wb_path);
  75.   stcgfp (wb->wb_dir,  wb->wb_path);
  76.   ObtainSemaphore (&Sema);
  77.   node = PatList.lh_Head;
  78.   while (node->ln_Succ)
  79.     {
  80.       if (((struct PatternNode *)node)->pn_Function == function)
  81.         {
  82.           if (((struct PatternNode *)node)->pn_PatternMode == PAT_MODE_NAME)
  83.             str = wb->wb_name;
  84.           else if (((struct PatternNode *)node)->pn_PatternMode == PAT_MODE_DIR)
  85.             str = wb->wb_dir;
  86.           else if (((struct PatternNode *)node)->pn_PatternMode == PAT_MODE_PATH)
  87.             str = wb->wb_path;
  88.           else
  89.             str = NULL;
  90.           if (str && MatchPatternNoCase (((struct PatternNode *)node)->pn_Match, str))
  91.             {
  92.               ReleaseSemaphore (&Sema);
  93.               return ((struct PatternNode *)node);
  94.             }
  95.         }
  96.       node = node->ln_Succ;
  97.     }
  98.   ReleaseSemaphore (&Sema);
  99.   return (NULL);
  100. }
  101.  
  102. //--------------------------------------------------------------------
  103. // Load settings (patterns' list)
  104.  
  105. BOOL LoadSets (void)
  106. {
  107.   struct PatternNode  *PN;
  108.   struct SetsHeader    SH;
  109.   struct PatternHeader PH;
  110.   BPTR SetsFH;
  111.   BOOL patch_t, convert = FALSE, result = GAME_OVER;
  112.   UBYTE dosfault[2*FAULT_MAX];
  113.  
  114.   patch_t = patch;
  115.   patch = FALSE;
  116.  
  117.   FreePatList();
  118.  
  119.   if (SetsFH = Open (SETS_FILE, MODE_OLDFILE))
  120.     {
  121.       if (Read (SetsFH, &SH, sizeof(struct SetsHeader)) == sizeof(struct SetsHeader))
  122.         {
  123.           if (SH.sh_ID == SETS_ID)
  124.             {
  125.               if (SH.sh_version <= SETS_VERSION)
  126.                 {
  127.                   if (SH.sh_version < SETS_VERSION)
  128.                     convert = TRUE;
  129.                   if (SH.sh_amount > 0L)
  130.                     {
  131.                       result = ALL_RIGHT;
  132.                       while (SH.sh_amount--)
  133.                         {
  134.                           if (PN = AllocVec (sizeof(struct PatternNode), MEMF_PUBLIC | MEMF_CLEAR))
  135.                             {
  136.                               if ((Read (SetsFH, &PH, sizeof(struct PatternHeader))   != sizeof(struct PatternHeader)) ||
  137.                                   (Read (SetsFH, PN->pn_Pattern,  PH.ph_PatternSize)  != PH.ph_PatternSize) ||
  138.                                   (Read (SetsFH, PN->pn_Storage,  PH.ph_StorageSize)  != PH.ph_StorageSize) ||
  139.                                   (Read (SetsFH, PN->pn_Password, PH.ph_PasswordSize) != PH.ph_PasswordSize))
  140.                                 {
  141.                                   MakeRequest (REQ_TITLE_ERROR, CANT_READ_SETS, CANCEL_BUT, SETS_FILE, FaultStr (IoErr(), dosfault));
  142.                                   FreeVec (PN);
  143.                                   result = GAME_OVER;
  144.                                   break;
  145.                                 }
  146.                               if (convert)
  147.                                 PN->pn_Function = 0;
  148.                               else
  149.                                 PN->pn_Function = PH.ph_Function;
  150.                               PN->pn_PatternMode   = PH.ph_PatternMode;
  151.                               PN->pn_StorageMode   = PH.ph_StorageMode;
  152.                               PN->pn_StorageMethod = PH.ph_StorageMethod;
  153.                               PN->pn_PerformCheck  = PH.ph_PerformCheck;
  154.                               if (PN->pn_UseXPK = PH.ph_UseXPK)
  155.                                 {
  156.                                   strcpy (PN->pn_XPKName, PH.ph_XPKName);
  157.                                   PN->pn_XPKMode = PH.ph_XPKMode;
  158.                                 }
  159.                               if (ParsePatternNoCase (PN->pn_Pattern, PN->pn_Match, 2*FMSIZE+8) < 0L)
  160.                                 {
  161.                                   MakeRequest (REQ_TITLE_ERROR, CANT_PARSE, CANCEL_BUT, PN->pn_Pattern, FaultStr (IoErr(), dosfault));
  162.                                   FreeVec (PN);
  163.                                   result = GAME_OVER;
  164.                                   break;
  165.                                 }
  166.                               PN->pn_Node.ln_Name = PN->pn_Match;
  167.                               ObtainSemaphore (&Sema);
  168.                               AddTail (&PatList, (struct Node *)PN);
  169.                               ReleaseSemaphore (&Sema);
  170.                             }
  171.                           else
  172.                             {
  173.                               MakeRequest (REQ_TITLE_ERROR, OUT_MEM, CANCEL_BUT, NULL);
  174.                               result = GAME_OVER;
  175.                               break;
  176.                             }
  177.                         }
  178.                     }
  179.                   else
  180.                     MakeRequest (REQ_TITLE_ERROR, NOT_SETS_FILE, CANCEL_BUT, SETS_FILE);
  181.                 }
  182.               else
  183.                 MakeRequest (REQ_TITLE_ERROR, NOT_SETS_FILE, CANCEL_BUT, SETS_FILE);
  184.             }
  185.           else
  186.             MakeRequest (REQ_TITLE_ERROR, NOT_SETS_FILE, CANCEL_BUT, SETS_FILE);
  187.         }
  188.       else
  189.         MakeRequest (REQ_TITLE_ERROR, CANT_READ_SETS, CANCEL_BUT, SETS_FILE, FaultStr (IoErr(), dosfault));
  190.       Close (SetsFH);
  191.     }
  192.   else
  193.     MakeRequest (REQ_TITLE_ERROR, CANT_OPEN_SETS, CANCEL_BUT, SETS_FILE, FaultStr (IoErr(), dosfault));
  194.   if (result)
  195.     patch = patch_t;
  196.   return (result);
  197. }
  198. //--------------------------------------------------------------------
  199. // Check for directory and file in Storage place
  200.  
  201. ULONG CheckStorage (struct WorkBuf *wb)
  202. {
  203.   UBYTE temp[FMSIZE], ch;
  204.   STRPTR t;
  205.   BPTR lock;
  206.   BOOL loop = TRUE;
  207.  
  208.   strcpy (temp, wb->wb_sdir);
  209.   if (t = strchr (temp, ':'))
  210.     {
  211.       ch = t[1]; t[1] = '\0';
  212.       if (lock = Lock (temp, ACCESS_READ))
  213.         {
  214.           t[1] = ch;
  215.           UnLock (lock);
  216.         }
  217.       else
  218.         {
  219.           MakeRequest (REQ_TITLE_ERROR, CANT_LOCK, CANCEL_BUT, temp, FaultStr (IoErr(), wb->wb_fault));
  220.           return (FUNK_CANCEL);
  221.         }
  222.     }
  223.   else
  224.     t = temp;
  225.   while (loop)
  226.     {
  227.       if (t = strchr (t, '/'))
  228.         *t = '\0';
  229.       else
  230.         loop = FALSE;
  231.       switch (getfa (temp))
  232.         {
  233.           case 0 :
  234.             if (_OSERR == ERROR_OBJECT_NOT_FOUND)
  235.               {
  236.                 if (lock = CreateDir (temp))
  237.                   {
  238.                     UnLock (lock);
  239.                     break;
  240.                   }
  241.                 MakeRequest (REQ_TITLE_ERROR, CANT_CREATE, CANCEL_BUT, temp, FaultStr (IoErr(), wb->wb_fault));
  242.                 return (FUNK_CANCEL);
  243.               }
  244.             MakeRequest (REQ_TITLE_ERROR, CANT_LOCK, CANCEL_BUT, temp, FaultStr (_OSERR, wb->wb_fault));
  245.             return (FUNK_CANCEL);
  246.           case -1:
  247.             MakeRequest (REQ_TITLE_ERROR, CANT_LOCK, CANCEL_BUT, temp, FaultStr (ERROR_OBJECT_WRONG_TYPE, wb->wb_fault));
  248.             return (FUNK_CANCEL);
  249.         }
  250.       if (t)
  251.         {
  252.           *t = '/';
  253.           t++;
  254.         }
  255.     }
  256.   switch (getfa (wb->wb_spath))
  257.     {
  258.       case 0 :
  259.         if (_OSERR == ERROR_OBJECT_NOT_FOUND)
  260.           return (FUNK_NO);
  261.         MakeRequest (REQ_TITLE_ERROR, CANT_LOCK, CANCEL_BUT, wb->wb_spath, FaultStr (_OSERR, wb->wb_fault));
  262.         break;
  263.       case 1 :
  264.         MakeRequest (REQ_TITLE_ERROR, CANT_LOCK, CANCEL_BUT, temp, FaultStr (ERROR_OBJECT_WRONG_TYPE, wb->wb_fault));
  265.         break;
  266.       case -1:
  267.         return (FUNK_YES);
  268.     }
  269.   return (FUNK_CANCEL);
  270. }
  271. //--------------------------------------------------------------------
  272. // Load of file needed for duplicate/backup
  273.  
  274. BOOL PrepareFile (struct PatternNode *pnode, struct WorkBuf *wb)
  275. {
  276.   BPTR fh;
  277.   struct FileInfoBlock *fib;
  278.   BOOL result = GAME_OVER;
  279.  
  280.   FreeWBuf (wb, FALSE);
  281.   if (fib = AllocDosObject (DOS_FIB, NULL))
  282.     {
  283.       if (fh = OldOpen (wb->wb_path, MODE_OLDFILE))
  284.         {
  285.           if (ExamineFH (fh, fib))
  286.             {
  287.               if (fib->fib_DirEntryType < 0)
  288.                 {
  289.                   if (wb->wb_inbuf = AllocVec (wb->wb_inlen = fib->fib_Size, MEMF_PUBLIC))
  290.                     {
  291.                       if (Read (fh, wb->wb_inbuf, wb->wb_inlen) == wb->wb_inlen)
  292.                         result = ALL_RIGHT;
  293.                       else
  294.                         MakeRequest (REQ_TITLE_ERROR, CANT_READ, CANCEL_BUT, wb->wb_path, FaultStr (IoErr(), wb->wb_fault));
  295.                     }
  296.                   else
  297.                     MakeRequest (REQ_TITLE_ERROR, OUT_MEM, CANCEL_BUT, NULL);
  298.                 }
  299.             }
  300.           else
  301.             MakeRequest (REQ_TITLE_ERROR, CANT_EXAM, CANCEL_BUT, wb->wb_path, FaultStr (IoErr(), wb->wb_fault));
  302.           OldClose (fh);
  303.         }
  304.       else
  305.         MakeRequest (REQ_TITLE_ERROR, CANT_OPEN, CANCEL_BUT, wb->wb_path, FaultStr (IoErr(), wb->wb_fault));
  306.       FreeDosObject (DOS_FIB, fib);
  307.     }
  308.   else
  309.     MakeRequest (REQ_TITLE_ERROR, OUT_MEM, CANCEL_BUT, NULL);
  310.   return (result);
  311. }
  312. //--------------------------------------------------------------------
  313. // Compare duplicated/backuped file with already presented one
  314.  
  315. BOOL PerformCheck (struct PatternNode *pnode, struct WorkBuf *wb)
  316. {
  317.   BPTR fh;
  318.   ULONG x;
  319.   STRPTR sbuf = NULL;
  320.   LONG   sbuf_len, xerr;
  321.   struct FileInfoBlock *fib;
  322.   struct XpkFib *xfib;
  323.   UBYTE xpkerr[XPKERRMSGSIZE];
  324.   BOOL result = FALSE;
  325.  
  326.   if (pnode->pn_UseXPK)
  327.     {
  328.       if (xfib = XpkAllocObject (XPKOBJ_FIB, NULL))
  329.         {
  330.           if (XpkExamineTags (xfib, XPK_InName, wb->wb_spath, XPK_GetError, xpkerr, TAG_DONE))
  331.             MakeRequest (REQ_TITLE_ERROR, CANT_EXAMXPK, CANCEL_BUT, wb->wb_spath, xpkerr);
  332.           else
  333.             {
  334.               if ((xfib->xf_ULen != wb->wb_inlen) || (strcmp (xfib->xf_Packer, pnode->pn_XPKName)))
  335.                 result = TRUE;
  336.               else
  337.                 {
  338.                   if (xerr = XpkUnpackTags (XPK_InName,        wb->wb_spath,
  339.                                             XPK_GetOutBuf,     &sbuf,
  340.                                             XPK_GetOutBufLen,  &sbuf_len,
  341.                                             XPK_OutMemType,    MEMF_PUBLIC,
  342.                                             XPK_Password,      pnode->pn_Password,
  343.                                             XPK_GetError,      xpkerr,
  344.                                             XPK_PassThru,      TRUE,
  345.                                             TAG_DONE))
  346.                     {
  347.                       if ((xerr == XPKERR_NEEDPASSWD) || (xerr == XPKERR_WRONGPW))
  348.                         result = TRUE;
  349.                       else
  350.                         MakeRequest (REQ_TITLE_ERROR, CANT_UNPACK, CANCEL_BUT, wb->wb_spath, xpkerr);
  351.                     }
  352.                   else
  353.                     {
  354.                       for (x = 0; x < wb->wb_inlen; x++)
  355.                         {
  356.                           if (wb->wb_inbuf[x] != sbuf[x])
  357.                             {
  358.                               result = TRUE;
  359.                               break;
  360.                             }
  361.                         }
  362.                     }
  363.                   if (sbuf)
  364.                     FreeMem (sbuf, sbuf_len);
  365.                 }
  366.             }
  367.           XpkFreeObject (XPKOBJ_FIB, xfib);
  368.         }
  369.       else
  370.         MakeRequest (REQ_TITLE_ERROR, OUT_MEM, CANCEL_BUT, NULL);
  371.     }
  372.   else
  373.     {
  374.       if (fib = AllocDosObject (DOS_FIB, NULL))
  375.         {
  376.           if (fh = OldOpen (wb->wb_spath, MODE_OLDFILE))
  377.             {
  378.               if (ExamineFH (fh, fib))
  379.                 {
  380.                   if (fib->fib_Size == wb->wb_inlen)
  381.                     {
  382.                       if (sbuf = AllocVec (fib->fib_Size, MEMF_PUBLIC))
  383.                         {
  384.                           if (Read (fh, sbuf, fib->fib_Size) == fib->fib_Size)
  385.                             {
  386.                               for (x = 0; x < wb->wb_inlen; x++)
  387.                                 {
  388.                                   if (wb->wb_inbuf[x] != sbuf[x])
  389.                                     {
  390.                                       result = TRUE;
  391.                                       break;
  392.                                     }
  393.                                 }
  394.                             }
  395.                           else
  396.                             MakeRequest (REQ_TITLE_ERROR, CANT_READ, CANCEL_BUT, wb->wb_spath, FaultStr (IoErr(), wb->wb_fault));
  397.                           FreeVec (sbuf);
  398.                         }
  399.                       else
  400.                         MakeRequest (REQ_TITLE_ERROR, OUT_MEM, CANCEL_BUT, NULL);
  401.                     }
  402.                   else
  403.                     result = TRUE;
  404.                 }
  405.               else
  406.                 MakeRequest (REQ_TITLE_ERROR, CANT_EXAM, CANCEL_BUT, wb->wb_spath, FaultStr (IoErr(), wb->wb_fault));
  407.               OldClose (fh);
  408.             }
  409.           else
  410.             MakeRequest (REQ_TITLE_ERROR, CANT_OPEN, CANCEL_BUT, wb->wb_spath, FaultStr (IoErr(), wb->wb_fault));
  411.           FreeDosObject (DOS_FIB, fib);
  412.         }
  413.       else
  414.         MakeRequest (REQ_TITLE_ERROR, OUT_MEM, CANCEL_BUT, NULL);
  415.     }
  416.   return (result);
  417. }
  418. //--------------------------------------------------------------------
  419. // Rename file(s) in Storage place
  420.  
  421. BOOL RenameSuffix (struct WorkBuf *wb)
  422. {
  423.   UWORD x;
  424.   STRPTR t_old, t_new;
  425.   BPTR lock;
  426.   UBYTE conv[8];
  427.   UBYTE temp_old[FMSIZE];
  428.   UBYTE temp_new[FMSIZE];
  429.  
  430.   t_old = stpcpy (temp_old, wb->wb_spath);
  431.   t_new = stpcpy (temp_new, wb->wb_spath);
  432.   *t_old = '.'; t_old++;
  433.   *t_new = '.'; t_new++;
  434. // delete file with suffix '99'
  435.   stci_d (conv, x = 99);
  436.   strcpy (t_old, conv);
  437.   if (lock = Lock (temp_old, ACCESS_READ))
  438.     {
  439.       UnLock (lock);
  440.       if (! OldDeleteFile (temp_old))
  441.         {
  442.           MakeRequest (REQ_TITLE_ERROR, CANT_DELETE, CANCEL_BUT, temp_old, FaultStr (IoErr(), wb->wb_fault));
  443.           return (FALSE);
  444.         }
  445.     }
  446.   else if (IoErr() != ERROR_OBJECT_NOT_FOUND)
  447.     {
  448.       MakeRequest (REQ_TITLE_ERROR, CANT_LOCK, CANCEL_BUT, temp_old, FaultStr (IoErr(), wb->wb_fault));
  449.       return (FALSE);
  450.     }
  451. // rename file(s) with suffix (x-1) to file(s) with suffix x
  452.   while (x)
  453.     {
  454.       x--;
  455.       strcpy (temp_new, temp_old);
  456.       stci_d (conv, x);
  457.       strcpy (t_old, conv);
  458.       if (Rename (temp_old, temp_new))
  459.         continue;
  460.       else if (IoErr() == ERROR_OBJECT_NOT_FOUND)
  461.         continue;
  462.       MakeRequest (REQ_TITLE_ERROR, CANT_RENAME, CANCEL_BUT, temp_old, FaultStr (IoErr(), wb->wb_fault));
  463.       return (FALSE);
  464.     }
  465. // rename file without suffix to file with suffix 0
  466.   strcpy (temp_new, temp_old);
  467.   t_old[-1] = '\0';
  468.   if (Rename (temp_old, temp_new))
  469.     return (TRUE);
  470.   if (IoErr() == ERROR_OBJECT_NOT_FOUND)
  471.     return (TRUE);
  472.   MakeRequest (REQ_TITLE_ERROR, CANT_RENAME, CANCEL_BUT, temp_old, FaultStr (IoErr(), wb->wb_fault));
  473.   return (FALSE);
  474. }
  475. //--------------------------------------------------------------------
  476. // Save duplicated/backuped file
  477.  
  478. void SaveFile (struct PatternNode *pnode, struct WorkBuf *wb)
  479. {
  480.   BPTR fh;
  481.   STRPTR buf = NULL, sbuf = NULL;
  482.   LONG len, s_len, sbuf_len;
  483.   UBYTE xpkerr[XPKERRMSGSIZE];
  484.  
  485.   if (pnode->pn_UseXPK)
  486.     {
  487.       if (XpkPackTags (XPK_InBuf,        wb->wb_inbuf,
  488.                        XPK_InLen,        wb->wb_inlen,
  489.                        XPK_GetOutBuf,    &sbuf,
  490.                        XPK_GetOutLen,    &s_len,
  491.                        XPK_GetOutBufLen, &sbuf_len,
  492.                        XPK_OutMemType,   MEMF_PUBLIC,
  493.                        XPK_PackMethod,   pnode->pn_XPKName,
  494.                        XPK_PackMode,     pnode->pn_XPKMode,
  495.                        XPK_Password,     pnode->pn_Password,
  496.                        XPK_GetError,     xpkerr,
  497.                        TAG_DONE))
  498.         MakeRequest (REQ_TITLE_ERROR, CANT_PACK, CANCEL_BUT, xpkerr);
  499.       else
  500.         {
  501.           buf = sbuf;
  502.           len = s_len;
  503.         }
  504.     }
  505.   else
  506.     {
  507.       buf = wb->wb_inbuf;
  508.       len = wb->wb_inlen;
  509.     }
  510.   if (buf)
  511.     {
  512.       if (fh = OldOpen (wb->wb_spath, MODE_NEWFILE))
  513.         {
  514.           if (Write (fh, buf, len) != len)
  515.             MakeRequest (REQ_TITLE_ERROR, CANT_WRITE, CANCEL_BUT, wb->wb_spath, FaultStr (IoErr(), wb->wb_fault));
  516.           OldClose (fh);
  517.         }
  518.       else
  519.         MakeRequest (REQ_TITLE_ERROR, CANT_OPEN, CANCEL_BUT, wb->wb_spath, FaultStr (IoErr(), wb->wb_fault));
  520.     }
  521.   if (sbuf)
  522.     FreeMem (sbuf, sbuf_len);
  523. }
  524. //--------------------------------------------------------------------
  525. // Create duplicated copy of file
  526.  
  527. LONG SpareIt (BPTR file, struct PatternNode *pnode, struct WorkBuf *wb)
  528. {
  529.   STRPTR t;
  530.   LONG result;
  531.   ULONG f_pres;
  532.   UBYTE temp[FMSIZE];
  533.  
  534.   if (! (result = OldClose (file)))
  535.     return (result);
  536.   if (! PrepareFile (pnode, wb))
  537.     return (result);
  538.  
  539.   if (pnode->pn_StorageMode == STO_MODE_FILE)
  540.     strcpy (wb->wb_sdir,  pnode->pn_Storage);
  541.   else if (pnode->pn_StorageMode == STO_MODE_DIR)
  542.     {
  543.       strcpy (temp, wb->wb_dir);
  544.       if (t = strchr (temp, ':'))
  545.         *t = '/';
  546.       strmfp (wb->wb_sdir, pnode->pn_Storage, temp);
  547.     }
  548.   else
  549.     return (result);
  550.   strmfp (wb->wb_spath, wb->wb_sdir, wb->wb_name);
  551.   if (! (f_pres = CheckStorage (wb)))
  552.     return (result);
  553.   if ((f_pres == FUNK_YES) && (pnode->pn_PerformCheck))
  554.     {
  555.       if (! PerformCheck (pnode, wb))
  556.         return (result);
  557.     }
  558.   if (pnode->pn_StorageMethod == STO_METHOD_REPLACE)
  559.     {
  560.       if (! OldDeleteFile (wb->wb_spath))
  561.         {
  562.           if (IoErr() != ERROR_OBJECT_NOT_FOUND)
  563.             {
  564.               MakeRequest (REQ_TITLE_ERROR, CANT_DELETE, CANCEL_BUT, wb->wb_spath, FaultStr (IoErr(), wb->wb_fault));
  565.               return (result);
  566.             }
  567.         }
  568.     }
  569.   else if (pnode->pn_StorageMethod == STO_METHOD_SUFFIX)
  570.     {
  571.       if (! RenameSuffix (wb))
  572.         return (result);
  573.     }
  574.   else
  575.     return (result);
  576.   SaveFile (pnode, wb);
  577.   return (result);
  578. }
  579. //--------------------------------------------------------------------
  580. // Create backuped copy of wrote file
  581.  
  582. BPTR BackupIt (STRPTR Name, LONG AccessMode, struct PatternNode *pnode, struct WorkBuf *wb)
  583. {
  584.   STRPTR t;
  585.   ULONG f_pres;
  586.   UBYTE temp[FMSIZE];
  587.  
  588.   if (! PrepareFile (pnode, wb))
  589.     return (OldOpen (Name, AccessMode));
  590.  
  591.   if (pnode->pn_StorageMode == STO_MODE_FILE)
  592.     strcpy (wb->wb_sdir,  pnode->pn_Storage);
  593.   else if (pnode->pn_StorageMode == STO_MODE_DIR)
  594.     {
  595.       strcpy (temp, wb->wb_dir);
  596.       if (t = strchr (temp, ':'))
  597.         *t = '/';
  598.       strmfp (wb->wb_sdir, pnode->pn_Storage, temp);
  599.     }
  600.   else
  601.     return (OldOpen (Name, AccessMode));
  602.   strmfp (wb->wb_spath, wb->wb_sdir, wb->wb_name);
  603.   if (! (f_pres = CheckStorage (wb)))
  604.     return (OldOpen (Name, AccessMode));
  605.  
  606.   if ((f_pres == FUNK_YES) && (pnode->pn_PerformCheck))
  607.     {
  608.       if (! PerformCheck (pnode, wb))
  609.         return (OldOpen (Name, AccessMode));
  610.     }
  611.  
  612.   if (pnode->pn_StorageMethod == STO_METHOD_REPLACE)
  613.     {
  614.       if (! OldDeleteFile (wb->wb_spath))
  615.         {
  616.           if (IoErr() != ERROR_OBJECT_NOT_FOUND)
  617.             {
  618.               MakeRequest (REQ_TITLE_ERROR, CANT_DELETE, CANCEL_BUT, wb->wb_spath, FaultStr (IoErr(), wb->wb_fault));
  619.               return (OldOpen (Name, AccessMode));
  620.             }
  621.         }
  622.     }
  623.   else if (pnode->pn_StorageMethod == STO_METHOD_SUFFIX)
  624.     {
  625.       if (! RenameSuffix (wb))
  626.         return (OldOpen (Name, AccessMode));
  627.     }
  628.   else
  629.     return (OldOpen (Name, AccessMode));
  630.   SaveFile (pnode, wb);
  631.   return (OldOpen (Name, AccessMode));
  632. }
  633. //--------------------------------------------------------------------
  634. // Create backuped copy of deleted file
  635.  
  636. BOOL AntiDelIt (STRPTR Name, struct PatternNode *pnode, struct WorkBuf *wb)
  637. {
  638.   STRPTR t;
  639.   ULONG f_pres;
  640.   UBYTE temp[FMSIZE];
  641.  
  642.   if (! PrepareFile (pnode, wb))
  643.     return (OldDeleteFile (Name));
  644.  
  645.   if (pnode->pn_StorageMode == STO_MODE_FILE)
  646.     strcpy (wb->wb_sdir,  pnode->pn_Storage);
  647.   else if (pnode->pn_StorageMode == STO_MODE_DIR)
  648.     {
  649.       strcpy (temp, wb->wb_dir);
  650.       if (t = strchr (temp, ':'))
  651.         *t = '/';
  652.       strmfp (wb->wb_sdir, pnode->pn_Storage, temp);
  653.     }
  654.   else
  655.     return (OldDeleteFile (Name));
  656.   strmfp (wb->wb_spath, wb->wb_sdir, wb->wb_name);
  657.   if (! (f_pres = CheckStorage (wb)))
  658.     return (OldDeleteFile (Name));
  659.  
  660.   if ((f_pres == FUNK_YES) && (pnode->pn_PerformCheck))
  661.     {
  662.       if (! PerformCheck (pnode, wb))
  663.         return (OldDeleteFile (Name));
  664.     }
  665.  
  666.   if (pnode->pn_StorageMethod == STO_METHOD_REPLACE)
  667.     {
  668.       if (! OldDeleteFile (wb->wb_spath))
  669.         {
  670.           if (IoErr() != ERROR_OBJECT_NOT_FOUND)
  671.             {
  672.               MakeRequest (REQ_TITLE_ERROR, CANT_DELETE, CANCEL_BUT, wb->wb_spath, FaultStr (IoErr(), wb->wb_fault));
  673.               return (OldDeleteFile (Name));
  674.             }
  675.         }
  676.     }
  677.   else if (pnode->pn_StorageMethod == STO_METHOD_SUFFIX)
  678.     {
  679.       if (! RenameSuffix (wb))
  680.         return (OldDeleteFile (Name));
  681.     }
  682.   else
  683.     return (OldDeleteFile (Name));
  684.   SaveFile (pnode, wb);
  685.   return (OldDeleteFile (Name));
  686. }
  687. //--------------------------------------------------------------------
  688. // Replace function for dos Close()
  689.  
  690. LONG __saveds __asm NewClose (register __d1 BPTR File)
  691. {
  692.   BPTR lock;
  693.   LONG result;
  694.   struct PatternNode *node;
  695.   struct WorkBuf *wb;
  696.  
  697.   if (patch)
  698.     {
  699.       if (wb = AllocWBuf())
  700.         {
  701.           if (NameFromFH (File, wb->wb_path, FMSIZE))
  702.             {
  703.               if (lock = DupLockFromFH (File))
  704.                 UnLock (lock);
  705.               else if (node = TracePatList (FUNCTION_SPARE, wb))
  706.                 {
  707.                   result = SpareIt (File, node, wb);
  708.                   FreeWBuf (wb, TRUE);
  709.                   return (result);
  710.                 }
  711.             }
  712.           FreeWBuf (wb, TRUE);
  713.         }
  714.     }
  715.   return (OldClose (File));
  716. }
  717. //--------------------------------------------------------------------
  718. // Replace function for dos Open()
  719.  
  720. BPTR __saveds __asm NewOpen (register __d1 STRPTR Name, register __d2 LONG AccessMode)
  721. {
  722.   BPTR lock, result;
  723.   struct PatternNode *node;
  724.   struct WorkBuf *wb;
  725.  
  726.   if (patch && (AccessMode != MODE_OLDFILE))
  727.     {
  728.       if (lock = Lock (Name, ACCESS_READ))
  729.         {
  730.           if (wb = AllocWBuf())
  731.             {
  732.               if (NameFromLock (lock, wb->wb_path, FMSIZE))
  733.                 {
  734.                   UnLock (lock);
  735.                   if (node = TracePatList (FUNCTION_BACKUP, wb))
  736.                     {
  737.                       result = BackupIt (Name, AccessMode, node, wb);
  738.                       FreeWBuf (wb, TRUE);
  739.                       return (result);
  740.                     }
  741.                 }
  742.               else
  743.                 UnLock (lock);
  744.               FreeWBuf (wb, TRUE);
  745.             }
  746.           else
  747.             UnLock (lock);
  748.         }
  749.     }
  750.   return (OldOpen (Name, AccessMode));
  751. }
  752. //--------------------------------------------------------------------
  753. // Replace function for dos DeleteFile()
  754.  
  755. BOOL __saveds __asm NewDeleteFile (register __d1 STRPTR Name)
  756. {
  757.   BPTR lock;
  758.   BOOL result;
  759.   struct PatternNode *node;
  760.   struct WorkBuf *wb;
  761.  
  762.   if (patch)
  763.     {
  764.       if (lock = Lock (Name, ACCESS_READ))
  765.         {
  766.           if (wb = AllocWBuf())
  767.             {
  768.               if (NameFromLock (lock, wb->wb_path, FMSIZE))
  769.                 {
  770.                   UnLock (lock);
  771.                   if (node = TracePatList (FUNCTION_ANTIDEL, wb))
  772.                     {
  773.                       result = AntiDelIt (Name, node, wb);
  774.                       FreeWBuf (wb, TRUE);
  775.                       return (result);
  776.                     }
  777.                 }
  778.               else
  779.                 UnLock (lock);
  780.               FreeWBuf (wb, TRUE);
  781.             }
  782.           else
  783.             UnLock (lock);
  784.         }
  785.     }
  786.   return (OldDeleteFile (Name));
  787. }
  788. //--------------------------------------------------------------------
  789. // Main work cycle of program
  790.  
  791. void MainLoop (void)
  792. {
  793.   struct Message *msg;
  794.   struct Task *PrefsTask;
  795.   ULONG Sig, MsgID, MsgType;
  796.   LONG retcode = 1L;
  797.  
  798.   patch = TRUE;
  799.   while (retcode)
  800.     {
  801.       Sig = Wait (SIGBREAKF_CTRL_C | cxsigflag);
  802.       while (msg = GetMsg (broker_mp))
  803.         {
  804.           MsgID   = CxMsgID ((CxMsg *)msg);
  805.           MsgType = CxMsgType ((CxMsg *)msg);
  806.           if (MsgType == CXM_COMMAND)
  807.             {                            // commodity messages
  808.               ReplyMsg (msg);
  809.               switch (MsgID)
  810.                 {
  811.                   case CXCMD_DISABLE   : // temporaly disabling of commodity
  812.                     ActivateCxObj (broker, patch = FALSE);
  813.                     break;
  814.                   case CXCMD_ENABLE    : // work again
  815.                     ActivateCxObj (broker, patch = TRUE);
  816.                     break;
  817.                   case CXCMD_KILL      : // stop commodity and quit
  818.                     retcode = 0L;
  819.                     break;
  820.                   case CXCMD_UNIQUE    : // run preferences editor
  821.                   case CXCMD_APPEAR    :
  822.                     SystemTags (ArgString (ttypes, PREFS_TOOLTYPES, PREFS_DEFAULT_PATH), SYS_Asynch, TRUE, TAG_DONE);
  823.                     break;
  824.                   case CXCMD_DISAPPEAR : // close preferences editor
  825.                     if (PrefsTask = FindTask (TASK_PREFS_NAME))
  826.                       Signal (PrefsTask, SIGBREAKF_CTRL_C);
  827.                     break;
  828.                 }
  829.             }
  830.           else
  831.             {                            // other messages
  832.               if (! strcmp (msg->mn_Node.ln_Name, PREFS_PORT_NAME)) 
  833.                 retcode = LoadSets();    // message from preferences editor - reload settings
  834.               ReplyMsg (msg);
  835.             }
  836.         }
  837.       if (Sig & SIGBREAKF_CTRL_C)
  838.         retcode = 0L;                    // break signal - quit
  839.     }
  840.   patch = FALSE;
  841. }
  842. /*                           ­¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¯
  843. ­¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¥        main()      ª¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¯
  844. ¢                            ¿¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡´                         ¢
  845. ¿¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡´
  846. */
  847. void main (ULONG argc, STRPTR *argv)
  848. {
  849.   LONG x;
  850.   struct Message *msg;
  851.  
  852.   if (IntuitionBase = OpenLibrary (INTUITION_LIBRARY_NAME, INTUITION_LIBRARY_VERSION))
  853.     {
  854.       if (LocaleBase = OpenLibrary (LOCALE_LIBRARY_NAME, LOCALE_LIBRARY_VERSION))
  855.         {
  856.           if (catalog = OpenCatalog (NULL, GETMES(CATALOG_NAME), OC_Version, CATALOG_LAST_VERSION, OC_BuiltInLanguage, GETMES(BUILTIN_LANGUAGE), TAG_DONE))
  857.             {
  858.               for (x = PROG_DESC; x < FINISH; x++)
  859.                 messages[x] = GetCatalogStr (catalog, x, GETMES(x));
  860.             }
  861.         }
  862.       if (XpkBase = OpenLibrary (XPK_LIBRARY_NAME, XPK_LIBRARY_VERSION))
  863.         {
  864.           ttypes = ArgArrayInit (argc, argv);
  865.           newbroker.nb_Descr = GETMES(PROG_DESC);
  866.           if (broker_mp = CreatePort (COM_PORT_NAME, 0))
  867.             {
  868.               newbroker.nb_Port = broker_mp;
  869.               if (broker = CxBroker (&newbroker, &x))
  870.                 {
  871.                   cxsigflag = 1L << broker_mp->mp_SigBit;
  872.                   ActivateCxObj (broker, 1L);
  873.                   NewList (&PatList);
  874.                   InitSemaphore (&Sema);
  875.                   if (LoadSets())
  876.                     {
  877.                       OldOpen       = (BPTR __asm (*)())SetFunction (DOSBase, (LONG)&LVOOpen,       (APTR)NewOpen);
  878.                       OldClose      = (LONG __asm (*)())SetFunction (DOSBase, (LONG)&LVOClose,      (APTR)NewClose);
  879.                       OldDeleteFile = (BOOL __asm (*)())SetFunction (DOSBase, (LONG)&LVODeleteFile, (APTR)NewDeleteFile);
  880.                       MainLoop();
  881.                       SetFunction (DOSBase, (LONG)&LVODeleteFile, (APTR)OldDeleteFile);
  882.                       SetFunction (DOSBase, (LONG)&LVOClose,      (APTR)OldClose);
  883.                       SetFunction (DOSBase, (LONG)&LVOOpen,       (APTR)OldOpen);
  884.                     }
  885.                   FreePatList();
  886.                   DeleteCxObj (broker);
  887.                 }
  888.               while (msg = GetMsg (broker_mp))
  889.                 ReplyMsg (msg);
  890.               DeletePort (broker_mp);
  891.             }
  892.           else
  893.             MakeRequest (REQ_TITLE_ERROR, CANT_MSGPORT, QUIT_BUT, NULL);
  894.           ArgArrayDone();
  895.           CloseLibrary (XpkBase);
  896.         }
  897.       else
  898.         MakeRequest (REQ_TITLE_ERROR, LIBRARY_PROBLEM, QUIT_BUT, XPK_LIBRARY_NAME, XPK_LIBRARY_VERSION);
  899.       if (LocaleBase)
  900.         {
  901.           CloseCatalog (catalog);
  902.           CloseLibrary (LocaleBase);
  903.         }
  904.       CloseLibrary (IntuitionBase);
  905.     }
  906. }
  907.